/**
 * 条件执行工具函数
 * 用于根据条件选择执行不同的函数
 */

/**
 * 条件匹配函数类型
 */
export type ConditionMatcher<T> = (value: T) => boolean;

/**
 * 条件项类型 - 可以是具体值或匹配函数
 */
export type ConditionItem<T> = T | ConditionMatcher<T>;

/**
 * 根据条件选择执行不同函数
 * @template T - 条件函数类型
 * @template A - 条件为真时的函数返回类型
 * @template B - 条件为假时的函数返回类型
 * @param {() => boolean} condition - 判断条件的函数
 * @param {() => A} whenTrue - 条件为真时执行的函数
 * @param {() => B} whenFalse - 条件为假时执行的函数
 * @returns {A | B} 执行结果
 * @example
 * const result = when(
 *   () => isUserLoggedIn(),
 *   () => getWelcomeMessage(),
 *   () => getLoginPrompt()
 * );
 */
export function when<T extends () => boolean, A, B>(
  condition: T,
  whenTrue: () => A,
  whenFalse: () => B
): A | B {
  return condition() ? whenTrue() : whenFalse();
}

/**
 * 条件执行的函数式实现
 * @template T - 输入参数类型
 * @template R - 函数返回类型
 * @param {(arg: T) => boolean} condition - 判断条件的函数
 * @param {(arg: T) => R} ifFn - 条件为真时执行的函数
 * @param {(arg: T) => R} elseFn - 条件为假时执行的函数
 * @returns {(arg: T) => R} 包装后的函数
 * @example
 * const processNumber = ifElse(
 *   num => num > 0,
 *   num => `正数: ${num}`,
 *   num => num < 0 ? `负数: ${num}` : '零'
 * );
 * 
 * console.log(processNumber(5));  // 正数: 5
 * console.log(processNumber(-3)); // 负数: -3
 * console.log(processNumber(0));  // 零
 */
export function ifElse<T, R>(
  condition: (arg: T) => boolean,
  ifFn: (arg: T) => R,
  elseFn: (arg: T) => R
): (arg: T) => R {
  return (arg: T) => condition(arg) ? ifFn(arg) : elseFn(arg);
}

/**
 * 高级条件处理器
 * 支持复杂的多条件组合匹配和处理
 * @template T - 条件值类型
 * @template R - 处理函数返回类型
 * @example
 * // 创建条件处理器
 * const handler = new AdvancedConditionHandler<boolean, void>()
 *   .rule([true, true], () => console.log('Both true'))
 *   .rule([true, false], () => console.log('First true, second false'))
 *   .rule([
 *     false,
 *     (val: boolean) => val === true // 使用函数条件
 *   ], () => console.log('Complex condition matched'))
 *   .otherwise(() => console.log('No rule matched'));
 * 
 * // 执行匹配的处理
 * handler.execute([true, false]); // 输出: First true, second false
 */
export class AdvancedConditionHandler<T, R> {
  private rules: { conditions: ConditionItem<T>[], handler: () => R }[] = [];
  private defaultHandler?: () => R;
  private endCallback?: (result: R) => void;

  /**
   * 添加条件规则
   * @param conditions 条件项数组，每个元素可以是具体值或匹配函数
   * @param handler 当条件匹配时执行的处理函数
   * @returns 当前实例，支持链式调用
   */
  rule(conditions: ConditionItem<T>[], handler: () => R): this {
    this.rules.push({ conditions, handler });
    return this;
  }

  /**
   * 设置默认处理函数
   * @param handler 当没有任何规则匹配时执行的默认处理函数
   * @returns 当前实例，支持链式调用
   */
  otherwise(handler: () => R): this {
    this.defaultHandler = handler;
    return this;
  }

  /**
   * 设置在execute执行结束时调用的回调函数
   * @param callback 回调函数，接收执行结果作为参数
   * @returns 当前实例，支持链式调用
   */
  end(callback: (result: R) => void): this {
    this.endCallback = callback;
    return this;
  }

  /**
   * 执行匹配的处理函数
   * @param values 实际值数组，将与规则中的条件进行匹配
   * @returns 匹配规则的处理函数返回值
   * @throws 当没有匹配的规则且未设置默认处理函数时抛出错误
   */
  execute(values: T[]): R {
    let result: R;
    
    for (const { conditions, handler } of this.rules) {
      if (this.matches(conditions, values)) {
        result = handler();
        // 在返回前执行end回调
        if (this.endCallback) {
          this.endCallback(result);
        }
        return result;
      }
    }

    if (this.defaultHandler) {
      result = this.defaultHandler();
      // 在返回前执行end回调
      if (this.endCallback) {
        this.endCallback(result);
      }
      return result;
    }

    const error = new Error(`No matching rule found for values: ${values.join(', ')}`);
    throw error;
  }

  /**
   * 检查条件数组是否与值数组匹配
   * @private
   * @param conditions 条件项数组
   * @param values 实际值数组
   * @returns 是否匹配
   */
  private matches(conditions: ConditionItem<T>[], values: T[]): boolean {
    // 条件数量与值数量必须一致
    if (conditions.length !== values.length) {
      return false;
    }

    // 逐一检查每个条件
    for (let i = 0; i < conditions.length; i++) {
      const condition = conditions[i];
      const value = values[i];

      // 如果是函数，执行函数进行匹配
      if (typeof condition === 'function') {
        const matcher = condition as ConditionMatcher<T>;
        if (!matcher(value)) {
          return false;
        }
      } else {
        // 否则进行值比较
        if (condition !== value) {
          return false;
        }
      }
    }

    return true;
  }
}